package www.dianbaozu.com.ui.server

import android.os.Bundle
import android.view.View
import androidx.core.view.isVisible
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.listener.OnLoadMoreListener
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.dylanc.loadinghelper.LoadingHelper
import com.dylanc.loadinghelper.ViewType
import com.lxj.xpopup.XPopup
import com.lxj.xpopup.core.BasePopupView
import com.lxj.xpopup.enums.PopupPosition
import com.netease.nim.uikit.api.NIMHelper
import com.netease.nimlib.sdk.team.constant.TeamMessageNotifyTypeEnum
import dagger.hilt.android.AndroidEntryPoint
import www.dianbaozu.com.R
import www.dianbaozu.com.databinding.FragmentServerBinding
import www.dianbaozu.com.ui.ProxyViewModel
import www.wen.com.common.lib.base.fragment.BaseListFragment
import www.wen.com.common.lib.base.module.BaseViewModel
import www.wen.com.common.lib.data.entities.*
import www.wen.com.common.lib.extension.*
import www.wen.com.common.lib.helper.loading.KeyHelper
import www.wen.com.common.lib.helper.loading.KeyHelper.BUNDLE_DATA
import www.wen.com.common.lib.helper.loading.KeyHelper.CLEAR_PREVIEW_INFO_KEY
import www.wen.com.common.lib.helper.loading.KeyHelper.INSERT_PREVIEW_SERVER_KEY
import www.wen.com.common.lib.helper.loading.KeyHelper.INVITE_JOINING_KEY
import www.wen.com.common.lib.helper.loading.KeyHelper.MMKV_IS_SHOW_EMPTY
import www.wen.com.common.lib.helper.loading.KeyHelper.REFRESHING_SERVER_LIST
import www.wen.com.common.lib.helper.loading.KeyHelper.REFRESHING_SERVER_LIST_KEY
import www.wen.com.common.lib.helper.loading.KeyHelper.REFRESHING_SERVER_LIST_KEY5
import www.wen.com.common.lib.helper.loading.KeyHelper.REFRESH_MY_KEY
import www.wen.com.common.lib.helper.loading.KeyHelper.TEAM_UNREAD_KEY
import www.wen.com.common.lib.helper.loading.LoadingAdapter
import www.wen.com.common.lib.helper.loading.NoTitleAdapter
import www.wen.com.common.lib.util.SpUtil
import www.wen.com.common.lib.view.popuview.ServerMenuPopupView

/**
 * @author WEN
 * @Description:主页服务器列表
 * @date 2020//25 17:48
 */
@AndroidEntryPoint
class ServerFragment :
    BaseListFragment<FragmentServerBinding, ServerSelfListEntity, ServerSelfListEntity.Content>(),
    View.OnClickListener,
    OnLoadMoreListener {

    private val proxyViewModel: ProxyViewModel by activityViewModels()

    private lateinit var mServerAdapter: ServerAdapter

    private var mPosition: Int = -1

    private var mPreviewPosition: Int = -1

    private var mIsAddFragment: Boolean = false

    private val serverViewModel: ServerViewModel by viewModels()

    override val viewModel: BaseViewModel
        get() = serverViewModel

    override val mIsEnableUseCustomEmpty: Boolean
        get() = true

    override fun customEmpty() {
        super.customEmpty()
        if (mServerAdapter.data.isEmpty() && !SpUtil.decodeBoolean(MMKV_IS_SHOW_EMPTY)) {
            dataBinding.clEmptyContainer.isVisible = true
        }
        if (mServerAdapter.data.isEmpty() && !SpUtil.decodeBoolean(KeyHelper.MMKV_IS_SHOW_EMPTY_TEXT)) {
            dataBinding.clHaveNotJoined.isVisible = true
        }
    }

    override val mRecyclerView: RecyclerView
        get() = dataBinding.rvServerList

    override val loadMoreEnd: Boolean
        get() = true

    override fun isEnableLoadingHelper(): Boolean = true

    override fun configurationLoadingHelper(loadingHelper: LoadingHelper): LoadingHelper {
        loadingHelper.register(ViewType.TITLE, getTitleBarUniversalAdapter())
        loadingHelper.register(ViewType.LOADING, LoadingAdapter())
        loadingHelper.setDecorHeader(ViewType.TITLE)
        return loadingHelper
    }

    override fun getTitleBarUniversalAdapter(): NoTitleAdapter =
        NoTitleAdapter(requireActivity(), true)

    override fun getLayoutId(): Int = R.layout.fragment_server

    override fun lazyInitView() {
        super.lazyInitView()
        observeListen()
        launchRequest(false)
    }

    private fun launchRequest(isRefresh: Boolean) {
        if (isRefresh) {
            mPreviewPosition = -1
            mPosition = 0
            serverViewModel.mPreviewServerMap.clear()
        }
        serverViewModel.requestGeneralListData(
            requiredParameter = RequestBodyParameter(),
            isRefresh = isRefresh
        ) {
            addOrRefreshFragment(isRefresh)
        }
    }

    private fun addOrRefreshFragment(isRefresh: Boolean) {

        if (isRefresh && !mServerAdapter.data.isNullOrEmpty()) mPosition = 0

        if (mServerAdapter.data.isNullOrEmpty()) return

        if (!mIsAddFragment) {
            mPosition = 0

            val serverListFragment = ServerListFragment()
            val bundle = Bundle()
            bundle.putParcelable(BUNDLE_DATA, mServerAdapter.data[0])
            serverListFragment.arguments = bundle
            childFragmentManager.beginTransaction().add(R.id.container, serverListFragment).commitAllowingStateLoss()

            dataBinding.clHaveNotJoined.isVisible = false
            SpUtil.encode(KeyHelper.MMKV_IS_SHOW_EMPTY_TEXT, true)

            mIsAddFragment = true

            invitationToServer()
        }
    }

    /**
     * 通过网页传参打开邀请界面，必须要等界面初始化完毕才可以去跳转到邀请链接，否则容易出现问题
     */
    private fun invitationToServer() {
        proxyViewModel.invitationUrl.observe(this) {
            if (it.isNotBlank()) {
                //判断是否已经打开邀请页面,未打开需要跳转,已打开则通过LiveEventBus传参刷新即可
                if (!requireActivity().isExitNavFragment(InviteJoiningServerFragment::class.java)) {
                    nav(R.id.action_mainFragment_to_inviteJoiningServerFragment, Bundle().apply {
                        putString(BUNDLE_DATA, it)
                    })
                } else {
                    postObject(INVITE_JOINING_KEY, it)
                }
                proxyViewModel.invitationUrl.value = ""
            }
        }
    }

    override fun onItemClick(adapter: BaseQuickAdapter<*, *>, view: View, position: Int) {
        super.onItemClick(adapter, view, position)
        if (mPosition != position) {
            val clickItemData = adapter.data[position] as ServerSelfListEntity.Content
            if(mPosition!=-1){
                val formerlyItemData = adapter.data[mPosition] as ServerSelfListEntity.Content
                formerlyItemData.isSelected = false
                adapter.notifyItemChanged(mPosition)
            }
            clickItemData.isSelected = true
            adapter.notifyItemChanged(position)
            mPosition = position
            postObject(REFRESHING_SERVER_LIST_KEY, mServerAdapter.data[mPosition])
        }
        removeAllPreviewContent()
    }

    /**
     * 移除所有的预览服务器
     */
    private fun removeAllPreviewContent() {
        if (mPreviewPosition != -1) {
            if (mPreviewPosition < mPosition) {
                serverViewModel.mPreviewServerMap.remove(mServerAdapter.data[mPreviewPosition].serverId)
                mServerAdapter.removeAt(mPreviewPosition)
                mPreviewPosition--
                mPosition--
            }
        }
    }

    override fun onReload() {
        launchRequest(false)
    }

    private fun observeListen() {
        serverViewModel.uiState.observe(this) {
            if (it.showSuccess != null) {

                if (it.isRefresh) {
                    mServerAdapter.setList(it.showSuccess)
                    if (mServerAdapter.data.isNotEmpty()) {
                        //假如不为空,刷新右边的列表
                        postObject(REFRESHING_SERVER_LIST_KEY, mServerAdapter.data[mPosition])
                    } else {
                        //假如为空，清空右边列表的数据
                        mPosition = -1
                        mPreviewPosition = -1
                        postObject(REFRESHING_SERVER_LIST_KEY5, Object())
                    }
                } else {
                    mServerAdapter.addData(it.showSuccess!!)
                }

                if (mPosition > 0) {
                    mServerAdapter.data[0].isSelected = false
                    mServerAdapter.data[mPosition].isSelected = true
                    mServerAdapter.notifyItemChanged(0)
                    mServerAdapter.notifyItemChanged(mPosition)
                }
                it.showSuccess?.forEach { entityContent ->
                    val teamMessageNotifyTypeEnum = when (entityContent.serverMember?.noticeType) {
                        "0" -> TeamMessageNotifyTypeEnum.Mute
                        "1" -> TeamMessageNotifyTypeEnum.All
                        //没有只显示@消息
                        "2" -> TeamMessageNotifyTypeEnum.Mute
                        else -> TeamMessageNotifyTypeEnum.All
                    }
                    entityContent.teamIds?.forEach { teamId ->
                        entityContent.serverMember
                        NIMHelper.muteTeam(teamId, teamMessageNotifyTypeEnum)
                        NIMHelper.updateMyTeamNick(
                            teamId,
                            entityContent.serverMember?.nickName ?: ""
                        )
                    }
                }
            }
        }
        //刷新左边的列表
        observeObject(REFRESHING_SERVER_LIST, this, Any::class.java) {
            launchRequest(true)
        }
//        //为了刷新列表的teamIds
//        observeObject(KeyHelper.REFRESHING_SERVER_LIST_KEY1, this, Any::class.java) {
//            launchRequest(true)
//        }
        //同步服务器中的频道昵称
        observeObject(REFRESH_MY_KEY, this, UseInfoEntity::class.java) {
            mServerAdapter.data.forEach { entityContent ->
                val teamMessageNotifyTypeEnum = when (entityContent.serverMember?.noticeType) {
                    "0" -> TeamMessageNotifyTypeEnum.Mute
                    "1" -> TeamMessageNotifyTypeEnum.All
                    //没有只显示@消息
                    "2" -> TeamMessageNotifyTypeEnum.Mute
                    else -> TeamMessageNotifyTypeEnum.All
                }
                if (entityContent.serverMember?.nickName == this.originalNickName) {
                    entityContent.serverMember?.nickName = this.nickName
                    entityContent.teamIds?.forEach { teamId ->
                        entityContent.serverMember
                        NIMHelper.muteTeam(teamId, teamMessageNotifyTypeEnum)
                        NIMHelper.updateMyTeamNick(
                            teamId,
                            this.nickName
                        )
                    }
                }
            }
        }
        //更新服务器logo
        observeObject(
            KeyHelper.UPDATE_SERVER_INFORMATION_KEY,
            this,
            ServerUpdateInfoEntity::class.java
        ) {
            mServerAdapter.data.forEachIndexed { i: Int, content: ServerSelfListEntity.Content ->
                if (serverId == content.serverId) {
                    serverLogo?.also { content.serverLogo = it }
                    mServerAdapter.notifyItemChanged(i)
                    return@forEachIndexed
                }
            }
        }

        //选中官方的服务器
        observeObject(
            KeyHelper.REFRESHING_SERVER_LIST_KEY2,
            this,
            ServerSelfListEntity.Content::class.java
        ) {
            var officialServerIndex = mServerAdapter.data.indexOfFirst { it.serverId == serverId }
            if (officialServerIndex != -1) {
                if (mPreviewPosition != -1) {
                    //移除预览的服务器
                    serverViewModel.mPreviewServerMap.remove(mServerAdapter.data[mPreviewPosition].serverId)
                    mServerAdapter.removeAt(mPreviewPosition)
                    mPreviewPosition--
                    officialServerIndex--
                    mPosition = officialServerIndex
                } else {
                    if (mPosition in 0..mServerAdapter.data.size) {
                        mServerAdapter.data[mPosition].isSelected = false
                        mServerAdapter.notifyItemChanged(mPosition)
                    }
                    if (officialServerIndex != mPosition) {
                        mPosition = officialServerIndex
                        mServerAdapter.data[mPosition].isSelected = true
                        mServerAdapter.notifyItemChanged(mPosition)
                        //刷新右边为官方服务器
                        postObject(REFRESHING_SERVER_LIST_KEY, mServerAdapter.data[mPosition])
                    }
                }
            } else {
                //左边的服务器列表如果没有官方服务器,则取消选中状态,直接显示右边的频道列表
                if (mPosition in 0..mServerAdapter.data.size) {
                    mServerAdapter.data[mPosition].isSelected = false
                    mServerAdapter.notifyItemChanged(mPosition)
                    mPosition = -1
                    //刷新右边为官方服务器
                    postObject(REFRESHING_SERVER_LIST_KEY, mServerAdapter.data[mPosition])
                }
            }
        }
        //选中指定的服务器并刷新右边的列表
        observeObject(
            KeyHelper.REFRESHING_SERVER_LIST_KEY3,
            this,
            ServerUpdateInfoEntity::class.java
        ) {
            val itemData = mServerAdapter.data[mPosition]
            if (itemData.serverId != serverId) {
                //假如有预览的服务器先移除
                if (mPreviewPosition != -1) {
                    serverViewModel.mPreviewServerMap.remove(mServerAdapter.data[mPreviewPosition].serverId)
                    mServerAdapter.removeAt(mPreviewPosition)
                    mPosition--
                    mPreviewPosition--
                }
                //找出需要展示服务器的下标
                val appointServerIndex = mServerAdapter.data.indexOfFirst {
                    it.serverId
                    serverId
                    it.serverId == serverId
                }
                if (appointServerIndex != -1) {
                    //假如列表存在指定的服务器下标
                    if (mPosition != -1 && mPosition != appointServerIndex) {
                        mServerAdapter.data[mPosition].isSelected = false
                        mServerAdapter.notifyItemChanged(mPosition)
                    }
                    mServerAdapter.data[appointServerIndex].isSelected = true
                    mServerAdapter.notifyItemChanged(appointServerIndex)
                    mPosition = appointServerIndex
                    //刷新右边列表
                    postObject(KeyHelper.REFRESHING_SERVER_LIST_KEY4, this)
                } else {
                    //列表不存在指定的服务器下标则取消现在选中的服务器,直接展示右边的列表
                    if (mPosition != -1 && mPosition in 0..mServerAdapter.data.size) {
                        mServerAdapter.data[mPosition].isSelected = false
                        mServerAdapter.notifyItemChanged(mPosition)
                    }
                    //刷新右边列表
                    postObject(KeyHelper.REFRESHING_SERVER_LIST_KEY4, this)
                }
            } else {
                //假如已经选择需要展示的服务器则刷新右边的列表
                postObject(KeyHelper.REFRESHING_SERVER_LIST_KEY1, Object())

                val teamMessageNotifyTypeEnum = when (itemData.serverMember?.noticeType) {
                    "0" -> TeamMessageNotifyTypeEnum.Mute
                    "1" -> TeamMessageNotifyTypeEnum.All
                    //没有只显示@消息
                    "2" -> TeamMessageNotifyTypeEnum.Mute
                    else -> TeamMessageNotifyTypeEnum.All
                }
                NIMHelper.muteTeam(this.teamId ?: "", teamMessageNotifyTypeEnum)
                NIMHelper.updateMyTeamNick(this.teamId ?: "", itemData.serverMember?.nickName ?: "")
            }
        }
        //插入预览的服务器
        observeObject(INSERT_PREVIEW_SERVER_KEY, this, ServerSelfListEntity.Content::class.java) {
            //如果列表已有预览服务器则移除
            if (mPreviewPosition != -1) {
                serverViewModel.mPreviewServerMap.remove(mServerAdapter.data[mPreviewPosition].serverId)
                mServerAdapter.removeAt(mPreviewPosition)
                mPosition--
                mPreviewPosition--
            }
            //取消原来选中的item
            if (mPosition != -1) {
                mServerAdapter.data[mPosition].isSelected = false
                mServerAdapter.notifyItemChanged(mPosition)
            }
            //在最上面插入新的预览服务器
            mServerAdapter.addData(0, this.apply { isSelected = true })
            mPosition = 0
            mPreviewPosition = 0
            //把预览服务器添加进入集合,防止后续预览服务器变为正式加入的服务器时，上拉加载时加载到重复的服务器
            serverViewModel.mPreviewServerMap[this.serverId] = this.serverId
            //滚动到第一个
            dataBinding.rvServerList.smoothScrollToPosition(0)
            //刷新右边的列表
            postObject(REFRESHING_SERVER_LIST_KEY, mServerAdapter.data[mPosition])
        }
        //清除已经插入预览的item中的serverGroups,因为服务器是否为预览主要看serverGroups是否等于null,如果为null就不是预览服务器了,这个消息是在加入预览服务器之后的操作
        observeObject(CLEAR_PREVIEW_INFO_KEY, this, Any::class.java) {
            if (mPreviewPosition != -1) {
                mServerAdapter.data[mPreviewPosition].serverGroups = null
                mPreviewPosition = -1
            }
        }
        //未读数更新
        observeObject(TEAM_UNREAD_KEY, this, TeamUnreadEntity::class.java) {
            mServerAdapter.data.forEachIndexed { index, content ->
                content.teamIds?.forEach {
                    if (this.contactId == it) {
                        mServerAdapter.notifyItemChanged(index)
                        return@forEachIndexed
                    }
                }
            }
        }

    }

    override fun onClick(v: View) {
        when (v.id) {
            R.id.ivAdd -> {
                XPopup.Builder(requireActivity())
                    .hasBlurBg(false)
                    .hasShadowBg(false)
                    .isDarkTheme(true)
                    .isDestroyOnDismiss(true)
                    .offsetX(50)
                    .offsetY(-20)
                    .atView(dataBinding.ivAdd)
                    .popupPosition(PopupPosition.Bottom)
                    .asCustom(ServerMenuPopupView(requireActivity(), ::showPopupView))
                    .show()
            }

            R.id.ivKnow -> {
                dataBinding.run {
                    SpUtil.encode(MMKV_IS_SHOW_EMPTY, true)
                    clEmptyContainer.isVisible = false
                }
            }
        }
    }

    private fun showPopupView(view: View, result: BasePopupView) {
        when (view.id) {
            R.id.llAddFriend -> {
                nav(R.id.action_mainFragment_to_addFriendFragment)
            }
            R.id.llCreateServer -> {
                nav(R.id.action_mainFragment_to_createServerFragment)
            }
            R.id.llJoinServer -> {
                nav(R.id.action_mainFragment_to_joiningServerFragment)
            }
        }
        result.dismiss()
    }


    override fun provideAdapter(): BaseQuickAdapter<ServerSelfListEntity.Content, BaseViewHolder> =
        ServerAdapter().apply {
            mServerAdapter = this
        }

    override fun onLoadMore() {
        launchRequest(false)
    }

}



